﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SceneLib;
using Tao.OpenGl;

namespace OpenGL
{
    class Vehicle
    {
        private SceneModel model;
        private Matrix rotationMatrix;
        private Vector translation;

        public Vehicle(SceneModel theModel)
        {
            model = theModel;
            rotationMatrix = Matrix.GetRotationMatrix(new Vector(), new Vector(), new Vector());
            translation = new Vector();
        }

        public void Rotation(Vector x, Vector y, Vector z)
        {
            Vector xC = x.Copy().Normalize3();
            Vector yC = y.Copy().Normalize3();
            Vector zC = z.Copy().Normalize3();
            rotationMatrix = Matrix.GetRotationMatrix(xC, yC, zC);
        }

        public void Translation(Vector v)
        {
            translation = v.Copy();
        }

        public void Draw()
        {
            Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR,
                            MathUtils.GetVector3Array(model.Triangles[0].Materials[0].Specular));
            Gl.glMaterialf(Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS,
                           model.Triangles[0].Materials[0].Shininess);
            SetTextures(model.Triangles[0].Materials[0]);

            Gl.glPushMatrix();

            Gl.glTranslatef(translation.x, translation.y, translation.z);
            Gl.glMultMatrixf(MathUtils.GetMatrixArray(rotationMatrix));
            Gl.glTranslatef(model.Position.x, model.Position.y, model.Position.z);
            Gl.glRotatef(model.Rotation.x, 1.0f, 0.0f, 0.0f);
            Gl.glRotatef(model.Rotation.y, 0.0f, 1.0f, 0.0f);
            Gl.glRotatef(model.Rotation.z, 0.0f, 0.0f, 1.0f);
            Gl.glScalef(model.Scale.x * 0.3f, model.Scale.y * 0.3f, model.Scale.z * 0.3f);

            Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
            Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
            Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);
            Gl.glEnableClientState(Gl.GL_COLOR_ARRAY);

            Gl.glNormalPointer(Gl.GL_FLOAT, 0, model.NormalsArray);
            Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, model.VertexArray);
            Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, model.TexArray);            
            Gl.glColorPointer(3, Gl.GL_FLOAT, 0, model.ColorArray);

            short[] indexes = model.IndexArray;
            Gl.glDrawElements(Gl.GL_TRIANGLES, indexes.Length,
                              Gl.GL_UNSIGNED_SHORT, indexes);

            Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
            Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
            Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
            Gl.glDisableClientState(Gl.GL_COLOR_ARRAY);
            Gl.glPopMatrix();
        }

        private void SetTextures(SceneMaterial sceneMat)
        {
            if (sceneMat.TextureImage != null)
            {

                Gl.glEnable(Gl.GL_TEXTURE_2D);

                sceneMat.CreatePointer();

                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);

                //Seteo de la textura usada
                Gl.glTexImage2D(Gl.GL_TEXTURE_2D,
                                0,
                                Gl.GL_RGBA,
                                sceneMat.TextureImage.Width,
                                sceneMat.TextureImage.Height,
                                0,
                                Gl.GL_BGR,
                                Gl.GL_UNSIGNED_BYTE,
                                sceneMat.PtrBitmap);
            }
            else
            {
                Gl.glDisable(Gl.GL_TEXTURE_2D);
            }
        }
    }
}
